package cn.uyunsky.platform.util.sql;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * <p>Description: nameSql解析器</p>
 * @version 1.0
 * @author baiyh
 */
public class ParameterRecognizer {

	public static final String SQL_SEPARATORS = " \n\r\f\t,()=<>&|+-=/*'^![]#~\\";
	public static final char POS_SIGN = ':';

	public static Map<Integer,String> parse(String nameSql) {

		Map<Integer,String> parameterMeta = new LinkedHashMap<Integer,String>();

		int stringLength = nameSql.length();
		boolean inQuote = false;

		//int position = 0;
		for (int indx = 0; indx < stringLength; indx++) {

			char c = nameSql.charAt(indx);
			if (inQuote) {
				if ('\'' == c) {
					inQuote = false;
				}
			} else if ('\'' == c) {
				inQuote = true;// 引号内的不处理
			} else {
				if (c == POS_SIGN) {
					// named parameter
					int right = firstIndexOfChar(nameSql, SQL_SEPARATORS, indx + 1);
					int chopLocation = right < 0 ? nameSql.length() : right;
					String param = nameSql.substring(indx + 1, chopLocation);
					if (isEmpty(param)) {
						throw new RuntimeException("Space is not allowed after parameter prefix ':' [" + nameSql + "]");
					}
					parameterMeta.put(indx++, param);
					//parameterMeta.put(position++, param);
					indx = chopLocation - 1;
				}
			}
		}// for end
		return parameterMeta;
	}

	private static int firstIndexOfChar(String sqlString, String string, int startindex) {
		int matchAt = -1;
		for (int i = 0; i < string.length(); i++) {
			int curMatch = sqlString.indexOf(string.charAt(i), startindex);
			if (curMatch >= 0) {
				if (matchAt == -1) { // first time we find match!
					matchAt = curMatch;
				} else {
					matchAt = Math.min(matchAt, curMatch);
				}
			}
		}
		return matchAt;
	}

	private static boolean isEmpty(String string) {
		return string == null || string.length() == 0;
	}

}
